package com.innovation.ic.im.end.base.service.im_erp9.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.innovation.ic.im.end.base.mapper.im_erp9.*;
import com.innovation.ic.im.end.base.model.im_erp9.Account;
import com.innovation.ic.im.end.base.model.im_erp9.TempAccount;
import com.innovation.ic.im.end.base.pojo.ServiceResult;
import com.innovation.ic.im.end.base.pojo.constant.Constants;
import com.innovation.ic.im.end.base.service.im_erp9.TempAccountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;

/**
 * @desc   TempAccount的具体实现类
 * @author linuo
 * @time   2022年7月5日16:35:25
 */
@Service
@Transactional
public class TempAccountServiceImpl extends ServiceImpl<TempAccountMapper, TempAccount> implements TempAccountService {
    private static final Logger log = LoggerFactory.getLogger(TempAccountServiceImpl.class);

    @Resource
    private TempAccountMapper tempAccountMapper;

    @Resource
    private AccountMapper accountMapper;

    @Resource
    private MessageMapper messageMapper;

    @Resource
    private GroupMessageMapper groupMessageMapper;

    @Resource
    private GroupMessageReceiverMapper groupMessageReceiverMapper;

    @Resource
    private UserGroupMessageMapper userGroupMessageMapper;

    @Resource
    private UserGroupMessageReceiverMapper userGroupMessageReceiverMapper;

    @Resource
    private RefUserGroupAccountMapper refUserGroupAccountMapper;

    /**
     * 删除account表中的所有数据
     * @return 返回删除结果
     */
    @Override
    public ServiceResult<Boolean> truncateTable() {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();

        // 删除temp_account表中的所有数据
        tempAccountMapper.truncateTable();

        serviceResult.setMessage(ServiceResult.DELETE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 备份account表中登录状态和最近登录时间不为空的数据
     */
    @Override
    public ServiceResult<Boolean> backupAccountLoginAndTimeIsNotNull() {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();

        // 查询account表中登录状态和最近登录时间不为空的数据
        List<TempAccount> list = tempAccountMapper.queryAccountLoginAndTimeIsNotNull();
        if(list != null && list.size() > 0){
            Integer count = tempAccountMapper.insertBatchSomeColumn(list);
            if(count > 0){
                log.info("account表中登录状态和最近登录时间不为空的数据备份成功,备份数据条数:[{}]", count);
            }
        }else{
            log.info("不存在account表中登录状态和最近登录时间不为空的数据,无需备份");
        }

        serviceResult.setMessage(ServiceResult.DELETE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 备份account表
     */
    @Override
    public ServiceResult<Boolean> backupAccount() {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();

        // 备份account表
        tempAccountMapper.backupAccount();

        serviceResult.setMessage(ServiceResult.DELETE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 将备份的TempAccount数据导入回原account表
     * @return 返回导入结果
     */
    @Override
    public ServiceResult<Boolean> insertTempAccountToAccount() {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();

        // 查询temp_account表中之前备份的数据
        List<TempAccount> tempAccounts = tempAccountMapper.queryAccountLoginAndTimeIsNotNull();
        if(tempAccounts != null && tempAccounts.size() > 0){
            // 将数据导入到account表
            int count = 0;
            for(TempAccount tempAccount : tempAccounts){
                Account account = new Account();

                // 通过erp9登录的状态。1表示已登录，0表示未登录
                if(tempAccount.getErp9Login() != null){
                    account.setErp9Login(tempAccount.getErp9Login());
                }

                // 最后一次登录时间
                if(tempAccount.getLastErp9LoginTime() != null){
                    account.setLastErp9LoginTime(tempAccount.getLastErp9LoginTime());
                }

                // 通过芯聊客户端登录的状态。1表示已登录，0表示未登录
                if(tempAccount.getXlLogin() != null){
                    account.setXlLogin(tempAccount.getXlLogin());
                }

                // 最后一次登录时间
                if(tempAccount.getLastXlLoginTime() != null){
                    account.setLastXlLoginTime(tempAccount.getLastXlLoginTime());
                }

                // 角色
                if(tempAccount.getRole() != null){
                    account.setRole(tempAccount.getRole());
                }

                UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq(Constants.ID, tempAccount.getId());
                updateWrapper.eq(Constants.USER_NAME, tempAccount.getUsername());

                int update = accountMapper.update(account, updateWrapper);
                if(update > 0){
                    count++;
                    log.info("导入用户:[{}]数据到account表完成,用户id:[{}]", tempAccount.getUsername(), tempAccount.getId());
                }
            }

            log.info("备份的TempAccount数据导入回原account表完成,导入数据条数:[{}]", count);
        }else{
            log.info("查询temp_account表中之前备份的数据为空,没有需要处理的数据");
        }

        // account和temp_account表对比，判断被删掉的用户账号，删除账号关联信息
        handleDeleteAccountData();

        serviceResult.setMessage(ServiceResult.DELETE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * account和temp_account表对比，判断被删掉的用户账号，删除账号关联信息
     */
    private void handleDeleteAccountData() {
        log.info("account和temp_account表对比,判断被删掉的用户账号,删除账号关联信息开始");
        // 比对account和temp_account表，获取在erp系统被删除的用户账号
        List<String> deleteAccounts = tempAccountMapper.queryErpDeleteAccountDatas();
        if(deleteAccounts != null && deleteAccounts.size() > 0){
            log.info("导入account数据后,account中有:[{}]条数据被删除,需要进行处理", deleteAccounts.size());
            for(String userName : deleteAccounts){
                // 处理一对一聊天记录数据，将删除用户发送的一对一消息数据设置为本人不可用
                messageMapper.setFromUserAvailable(userName);

                // 处理默认群组聊天记录数据，将删除用户发送的默认群组消息数据设置为本人不可用，并且接收到的消息设置为本人不可用
                handleDeleteGroupMessage(userName);

                // 处理自定义群组聊天数据，将删除用户发送的自定义群组消息设置为本人不可用，并且接收到的消息设置为本人不可用
                handleDeleteUserGroupMessage(userName);

                // 从自定义群组中将用户删除，更新自定义群组成员数量
                handleUserGroupAccountData(userName);
            }
        }else{
            log.info("导入前后数据数量一致,无需处理");
        }
        log.info("account和temp_account表对比，判断被删掉的用户账号，删除账号关联信息结束");
    }

    /**
     * 从自定义群组中将用户删除，更新自定义群组成员数量
     * @param userName 用户名
     */
    private void handleUserGroupAccountData(String userName) {
        // 查找包含当前用户的自定义群组id
        List<Integer> userGroupIds = refUserGroupAccountMapper.selectIncludeUserNameGroupIds(userName);
        if(userGroupIds != null && userGroupIds.size() > 0){
            for(Integer userGroupId : userGroupIds){
                // 将当前用户从自定义群组中删除
                refUserGroupAccountMapper.deleteUserFromUserGroup(userGroupId, userName);

                // 更新自定义群组成员数量
                refUserGroupAccountMapper.updateUserGroupMemberCount(userGroupId);
            }
        }
    }

    /**
     * 处理自定义群组聊天数据，将删除用户发送的自定义群组消息设置为本人不可用，并且接收到的消息设置为本人不可用
     * @param userName 用户名
     */
    private void handleDeleteUserGroupMessage(String userName) {
        // 将删除用户发送的自定义群组消息数据设置为本人不可用
        userGroupMessageMapper.setFromUserAvailable(userName);

        // 自定义群组中本人接收到的消息设置为不可用
        userGroupMessageReceiverMapper.setToUserAvailable(userName);
    }

    /**
     * 处理默认群组聊天记录数据，将删除用户发送的默认群组消息数据设置为本人不可用，并且接收到的消息设置为本人不可用
     * @param userName 用户名
     */
    private void handleDeleteGroupMessage(String userName) {
        // 将删除用户发送的默认群组消息数据设置为本人不可用
        groupMessageMapper.setFromUserAvailable(userName);

        // 默认群组中本人接收到的消息设置为不可用
        groupMessageReceiverMapper.setToUserAvailable(userName);
    }
}